#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using XNALibrary.Interfaces;
using XNALibrary.Cameras;
using XNALibrary.Entities;
using XNALibrary.Skybox;
using XNALibrary.PostProcessing;
using XNALibrary.Landspace;
using XNALibrary.Game;
#endregion

namespace Test1
{
    public class SceneCar : State
    {
        private Model model;
        private Model groundModel;
        private Vector3 targetColor = Color.Orange.ToVector3();
        private FillMode fillMode;

        public SceneCar()
        {
            
        }

        public override void Initialize()
        {
            base.Initialize();
            model = BaseGame.content.Load<Model>("Content/Models/Car");
            groundModel = BaseGame.content.Load<Model>("Content/Models/Ground");
            fillMode = FillMode.Solid;
        }

        public override void Update()
        {
            GamePadState gamePad = GamePad.GetState(PlayerIndex.One);
            if (gamePad.Buttons.A == ButtonState.Pressed)
                fillMode = FillMode.Solid;
            if (gamePad.Buttons.X == ButtonState.Pressed)
                fillMode = FillMode.WireFrame;

        }

        public override void Draw()
        {
            DrawModel(groundModel, Matrix.Identity, BaseGame.camera);
            BaseGame.device.RenderState.FillMode = fillMode;
            DrawCar(Matrix.CreateTranslation(0, 1, 0), BaseGame.camera);
            BaseGame.device.RenderState.FillMode = FillMode.Solid;
        }

        private void DrawCar(Matrix world, ICamera camera)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            foreach (ModelMesh mesh in model.Meshes)
            {
                Matrix boneWorld = transforms[mesh.ParentBone.Index] * Matrix.CreateScale(500) * world;

                foreach (Effect effect in mesh.Effects)
                {
                    // The car model has been modified to reference ReplaceColor.fx
                    // The parameters need to be set differently for that effect
                    BasicEffect basicEffect = effect as BasicEffect;
                    if (basicEffect != null)
                    {
                        // Set parameters on a BasicEffect
                        basicEffect.EnableDefaultLighting();
                        basicEffect.World = boneWorld;
                        basicEffect.View = camera.View;
                        basicEffect.Projection = camera.Projection;
                    }
                    else
                    {
                        // Set parameters on a color replacement effect
                        effect.Parameters["WorldViewProjection"].SetValue(
                            boneWorld * camera.View * camera.Projection);
                        effect.Parameters["World"].SetValue(boneWorld);
                        effect.Parameters["TargetColor"].SetValue(targetColor);
                    }
                }
                mesh.Draw();
            }
        }

        private void DrawModel(Model model, Matrix world, ICamera camera)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.PreferPerPixelLighting = true;
                    effect.World = transforms[mesh.ParentBone.Index] * world;

                    // Use the matrices provided by the chase camera
                    effect.View = camera.View;
                    effect.Projection = camera.Projection;
                }
                mesh.Draw();
            }
        }
    }
}